<?php
namespace App\Common\Cla\ClaBase;

use App\Common as com;

abstract class SaveV2 extends com\Cla\ClaBase {

	/**
	 * 保存过程数据（保存后自动清除）
	 * @var array
	 */
	protected array $saveRuntimeData = [];

	/**
	 * @return com\Model\Base\DataManager
	 */
	abstract public function goWaitSaveDataManager():com\Model\Base\DataManager;

	/**
	 * @param \Closure $fn
	 * @return $this
	 */
	public function goWaitSaveDataManagerClosure( \Closure $fn ):self {
		call_user_func( $fn, $this->goWaitSaveDataManager() );
		//
		return $this;
	}

	/**
	 * 检查是否允许保存
	 * @param bool $isCreate 是否为创建模式
	 * @return string|bool [true]允许 [false]不允许创建 [string]不允许，并返回错误提示
	 */
	protected function checkSaveReStr( bool $isCreate ):string|bool {
		return true;
	}

	/**
	 * 保存
	 * @return bool
	 * @throws
	 */
	public function save(  ):bool {
		try{
			$isCreate = $this->goWaitSaveDataManager()->isCreate();
			// 检查是否允许保存
			$repeatStr = $this->checkSaveReStr( $isCreate );
			if( $repeatStr !== true ){
				if( $repeatStr === false ){
					return false;
				}else{
					throw com\Lib\Err\Exception::makeOfNew( $repeatStr, com\Lib\Err\Code::$sysSqlDataExist );
				}
			}
			// 事件->保存前
			if( ! $this->eventSaveBefore( $isCreate ) ){
				return false;
			}
			//
			com\Lib\Db::transactionCheckFalse( function() use ( $isCreate ){
				// 事件->保存前(事务内)
				if( ! $this->eventSaveBeforeAsTransaction( $isCreate ) ){
					return false;
				}
				// 保存
				$this->goWaitSaveDataManager()->saveAllReThis();
				//
				// 事件->保存后(事务内)
				if( ! $this->eventSaveLaterAsTransaction( $isCreate, $this->goWaitSaveDataManager()->getMainDataIdOfClient() ) ){
					return false;
				}
			} );
			// 事件->保存后
			if( ! $this->eventSaveLater( $isCreate, $this->goWaitSaveDataManager()->getMainDataIdOfClient() ) ){
				return false;
			}
			//
			return true;
		} finally{
			$this->saveRuntimeData = [];
		}
	}

	/**
	 * 创建并返回数据id
	 * @return int 数据id
	 * @throws
	 */
	public function saveReMainId():int {
		$this->save();
		//
		return $this->goWaitSaveDataManager()->getMainDataIdOfClient();
	}

	/**
	 * 创建并返回数据id(父表主id)
	 * @return int 数据id
	 * @throws
	 */
	public function saveReParentMainId():int {
		$this->save();
		//
		return $this->goWaitSaveDataManager()->getMainDataIdOfParent();
	}

	/**
	 * 事件->保存前
	 * @param bool $isCreate 是否为创建模式
	 * @return bool 是否继续执行
	 */
	protected function eventSaveBefore( bool $isCreate ):bool {
		return true;
	}

	/**
	 * 事件->保存前(事务内)
	 * @param bool $isCreate 是否为创建模式
	 * @return bool 是否继续执行
	 */
	protected function eventSaveBeforeAsTransaction( bool $isCreate ):bool {
		return true;
	}

	/**
	 * 事件->保存后
	 * @param bool $isCreate 是否为创建模式
	 * @param int $dataId
	 * @return bool 是否继续执行
	 */
	protected function eventSaveLater( bool $isCreate, int $dataId ):bool {
		return true;
	}

	/**
	 * 事件->保存后(事务内)
	 * @param bool $isCreate 是否为创建模式
	 * @param int $dataId
	 * @return bool 是否继续执行
	 */
	protected function eventSaveLaterAsTransaction( bool $isCreate, int $dataId ):bool {
		return true;
	}

}
